/*
//   Copyright 2008 Dear Soft(http://dear-soft.com)
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.
 */

package com.dear.soft.components.properties;

import com.dear.soft.components.properties.renderers.RefereceImpl;
import com.dear.soft.components.properties.renderers.ReferenceExpander;
import com.dear.soft.components.properties.renderers.ReferenceName;
import com.dear.soft.components.properties.renderers.ReferenceValue;

public class PropertyDescriptor implements Comparable<PropertyDescriptor> {
	public final String name;
	public final String description;

	private final PropertyExpander expanderRef;
	private final PropertyValue valueRef;
	private final PropertyName nameRef;

	public Object value;
	public Integer order = null;

	public PropertyDescriptor(String name, String description, Object value) {
		super();
		this.name = name;
		this.description = description;
		this.value = value;
		this.expanderRef = new PropertyExpander(this);
		this.valueRef = new PropertyValue(this);
		this.nameRef = new PropertyName(this);
	}

	public String getName() {
		return name;
	}

	public String getDescription() {
		return description;
	}

	public Object getValue() {
		return value;
	}

	public void setValue(Object value) {
		this.value = value;
	}

	public PropertyExpander getExpanderRef() {
		return expanderRef;
	}

	public PropertyValue getValueRef() {
		return valueRef;
	}

	public PropertyName getNameRef() {
		return nameRef;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result
				+ ((description == null) ? 0 : description.hashCode());
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		result = prime * result + ((value == null) ? 0 : value.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		final PropertyDescriptor other = (PropertyDescriptor) obj;
		if (description == null) {
			if (other.description != null)
				return false;
		} else if (!description.equals(other.description))
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		if (value == null) {
			if (other.value != null)
				return false;
		} else if (!value.equals(other.value))
			return false;
		return true;
	}

	public static class PropertyExpander extends
			RefereceImpl<PropertyDescriptor> implements
			ReferenceExpander<PropertyDescriptor> {
		public PropertyExpander(PropertyDescriptor ref) {
			super(ref);
		}
	}

	public static class PropertyName extends RefereceImpl<PropertyDescriptor>
			implements ReferenceName<PropertyDescriptor> {
		public PropertyName(PropertyDescriptor ref) {
			super(ref);
		}
	}

	public static class PropertyValue extends RefereceImpl<PropertyDescriptor>
			implements ReferenceValue<PropertyDescriptor> {
		public PropertyValue(PropertyDescriptor ref) {
			super(ref);
		}
	}

	@Override
	public int compareTo(PropertyDescriptor o) {
		if (o == null) {
			return -1;
		}
		int res = 0;
		if (order != null) {
			res = order.compareTo(o.getOrder());
		}
		if (res == 0) {
			res = name.compareTo(o.getName());
		}
		if (res == 0) {
			return new Integer(hashCode()).compareTo(o.hashCode());
		}
		return res;
	}

	public int getOrder() {
		return order;
	}

	public void setOrder(int order) {
		this.order = order;
	}
}
